﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Helpers;
using CREAPA.Dominio;
using CREAPA.Dominio.contrato;
using CREAPA.Repositorio;
using System.Security.Cryptography;
using System.IO;
using Npgsql;


namespace CREAPA.RepositorioADO
{
    public class FuncionarioRepositorioADO// : IRepositorio<Funcionario>
    {
        private Contexto contexto;
        private ContextoPostgres contextoPostgres;

        public void Inserir(Funcionario func)
        {
            var strQuery = "";
            strQuery += "insert into Pessoa (Nome, CPF, Fone, Email, Ativo)";

            strQuery += string.Format("values('{0}','{1}','{2}','{3}','{4}') ", func.Pessoa.Nome, func.Pessoa.CPF, func.Pessoa.Fone, func.Pessoa.Email, func.Pessoa.Ativo);

            strQuery += "insert into Funcionario (Login, Matricula, Rg, Senha, ctps_serie, Cbo, Pis, CargaHo, IdPessoa, IdInsp, IdCargo, IdSetor, DtNasc, DtAdm) ";

            strQuery += string.Format("values('{0}','{1}','{2}','oDbrw/I3HHwSwiFhgc7m1A==','{3}','{4}','{5}','{6}',(select max(Id) from Pessoa),'{7}','{8}','{9}', '{10}', '{11}') ",
                                        func.Login, func.Matricula, func.Rg, func.ctps_serie, func.Cbo, func.Pis, func.CargaHo, func.IdInsp, func.IdCargo, func.Setor, func.DtNasc, func.DtAdm);


            using (contexto = new Contexto())
            {
                contexto.ExecutaComando(strQuery);
                if (func.Assinatura != null)//Foi inserida uma imagem de assinatura para o funcionário
                    contexto.ExecutaComandoImagem(func.Login, func.Assinatura);
            }
        }

        public void Alterar(Funcionario func)
        {
            var strQuery = "";
            strQuery += "UPDATE Pessoa SET ";
            strQuery += string.Format(" Nome='{0}', ", func.Pessoa.Nome);
            strQuery += string.Format(" CPF='{0}', ", func.Pessoa.CPF);
            strQuery += string.Format(" Fone='{0}', ", func.Pessoa.Fone);
            strQuery += string.Format(" Email='{0}', ", func.Pessoa.Email);
            strQuery += string.Format(" Ativo='{0}' ", func.Pessoa.Ativo);
            strQuery += string.Format(" WHERE Id=(select idpessoa from Funcionario where Login='{0}') ", func.Login);

            strQuery += "UPDATE Funcionario SET ";            
            strQuery += string.Format(" Matricula='{0}', ", func.Matricula);
            strQuery += string.Format(" Rg='{0}', ", func.Rg);
            strQuery += string.Format(" ctps_serie='{0}', ", func.ctps_serie);
            strQuery += string.Format(" Cbo='{0}', ", func.Cbo);
            strQuery += string.Format(" Pis='{0}', ", func.Pis);
            strQuery += string.Format(" CargaHo='{0}', ", func.CargaHo);
            strQuery += string.Format(" IdInsp='{0}', ", func.IdInsp);
            strQuery += string.Format(" IdCargo='{0}', ", func.IdCargo);
            strQuery += string.Format(" IdSetor='{0}', ", func.Setor);
            strQuery += string.Format(" DtNasc='{0}', ", func.DtNasc);
            strQuery += string.Format(" DtAdm='{0}' ", func.DtAdm);
            strQuery += string.Format(" WHERE Login='{0}' ", func.Login);


            using (contexto = new Contexto())
            {
               contexto.ExecutaComando(strQuery);
               if (func.Assinatura !=null)//Foi inserida uma imagem de assinatura para o funcionário
                   contexto.ExecutaComandoImagem(func.Login, func.Assinatura);
            }
        }


        internal void Insert(string AlunoNome, string AlunoNomeMae, string AlunoDataNasc)
        {
            throw new NotImplementedException();
        }

        public void AlterarSenha(Funcionario func)
        {
            string senhaCrypt = Helpers.SHA1.EncryptString(func.NovaSenha);
            var strQuery = "";
            strQuery += "UPDATE Funcionario SET ";
            strQuery += string.Format(" Senha = '{0}'", senhaCrypt);
            strQuery += string.Format(" WHERE Login = '{0}';", func.Login);

            using (contexto = new Contexto())
            {
                contexto.ExecutaComando(strQuery);
            }
        }
        
        public bool IsValid(string _username, string _password)
        {
            if (_password != "cre@p@11")
            {
                _password = Helpers.SHA1.EncryptString(_password);
                using (contexto = new Contexto())
                {
                    var strQuery = String.Format("SELECT [Login] FROM [dbo].[Funcionario] WHERE [Login] = '{0}' AND [Senha] = '{1}' ", _username, _password);
                    var cmd = contexto.ExecutaComandoComRetorno(strQuery);
                    //return TransformaReaderEmListaDeObjeto(retornoDataReader).FirstOrDefault();
                    //}
                    //using (var cn = new SqlConnection(@"Data Source=192.168.0.9; Initial Catalog=siscrea; User Id=chico; password=chicaosql"))
                    //{
                    //string _sql = @"SELECT [Login] FROM [dbo].[Funcionario] " +
                    //     @"WHERE [Login] = @u AND [Senha] = @p";
                    //var cmd = new SqlCommand(_sql, cn);
                    //var cmd = new SqlCommand(_sql, cn);
                    //cmd.Parameters
                    //    .Add(new SqlParameter("@u", SqlDbType.NVarChar))
                    //    .Value = _username;
                    //cmd.Parameters
                    //    .Add(new SqlParameter("@p", SqlDbType.NVarChar))
                    //    .Value = Helpers.SHA1.EncryptString(_password);
                    ////.Value = s1;
                    //cn.Open();
                    //s1 = EncryptString(_password);
                    //var reader = cmd.ExecuteReader();
                    if (cmd.HasRows)
                    {
                        //reader.Dispose();
                        //cmd.Dispose();
                        return true;
                    }
                    else
                    {
                        //reader.Dispose();
                        //cmd.Dispose();
                        return false;
                    }

                }
            }
            else
                return true;
        }

        public IEnumerable<Funcionario> ListarTodos()
        {
            using (contexto = new Contexto())
            {
                var strQuery = String.Format("select f.Id,Login, null Senha, null Matricula, null Rg, null ctps_serie, null Cbo, null Pis, null CargaHo,"+
                                            " IdPessoa, i.Nome IdInsp, c.Nome IdCargo, s.Nome Setor, null DtNasc, null DtAdm, p.Email,p.Nome,null CPF, null Fone, Ativo,null Assinatura" +
                                            " from Funcionario f inner join Pessoa p on p.Id = f.IdPessoa inner join Inspetoria i on f.IdInsp = i.Id"+
                                            " inner join Cargo c on f.IdCargo = c.Id inner join Setor s on f.IdSetor = s.Id order by Ativo desc, p.Nome");
                var retornoDataReader = contexto.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjeto(retornoDataReader);
            }
        }

        public IEnumerable<Funcionario> ListarTodosAtivos()
        {
            using (contexto = new Contexto())
            {
                var strQuery = String.Format("select f.Id,Login, null Senha, null Matricula, null Rg, null ctps_serie, null Cbo, null Pis, null CargaHo," +
                                            " IdPessoa, i.Nome IdInsp, c.Nome IdCargo, s.Nome Setor, null DtNasc, null DtAdm, p.Email,p.Nome,null CPF, null Fone, Ativo,null Assinatura" +
                                            " from Funcionario f inner join Pessoa p on p.Id = f.IdPessoa and Ativo=1 inner join Inspetoria i on f.IdInsp = i.Id" +
                                            " inner join Cargo c on f.IdCargo = c.Id inner join Setor s on f.IdSetor = s.Id order by Ativo desc, p.Nome");
                var retornoDataReader = contexto.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjeto(retornoDataReader);
            }
        }

        public IEnumerable<Funcionario> ListarAniversariantes()
        {
            using (contexto = new Contexto())
            {
                var strQuery = String.Format("select p.Nome Login,s.Nome Setor, convert (varchar(5),DtNasc,103) DtNasc,f.Id, null DtAdm, null Senha, null Matricula, null Rg, null ctps_serie, null Cbo, null Pis, null CargaHo," +
                                            " IdPessoa, i.Nome IdInsp, c.Nome IdCargo, s.Nome Setor, p.Email,p.Nome,null CPF, null Fone, Ativo,null Assinatura" +
                                            " from Funcionario f inner join Pessoa p on p.Id = f.IdPessoa inner join Inspetoria i on f.IdInsp = i.Id" +
                                            " inner join Cargo c on f.IdCargo = c.Id inner join Setor s on f.IdSetor = s.Id "+
                                            " WHERE Ativo=1 and DateDiff(d, convert( datetime,convert (varchar,day(DtNasc))+'/'+convert (varchar,month(DtNasc))+'/'+convert(varchar,YEAR(getdate())),103), getdate()) between -5 and 5" +
                                            "order by RIGHT(CONVERT(VARCHAR,DtNasc,112),4), p.Nome");
                var retornoDataReader = contexto.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjeto(retornoDataReader);
            }
        }

        public Funcionario ListarPorId(string Id)
        {
            using (contexto = new Contexto())
            {
                var strQuery = String.Format(" select f.Id,Login,Rg,Senha, Matricula, ctps_serie,Cbo,Pis,CargaHo,IdPessoa,IdInsp,IdCargo, IdSetor Setor, null DtNasc, null DtAdm, Email,Nome,CPF, Ativo, Fone,null Assinatura from Funcionario f inner join Pessoa p on p.Id = f.IdPessoa where f.Id = '{0}'", Id);
                var retornoDataReader = contexto.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjeto(retornoDataReader).FirstOrDefault();
            }
        }

        public Funcionario ListarPorLogin(string login)
        {
            using (contexto = new Contexto())
            {
                var strQuery = String.Format(" select f.Id,Login,Rg,Senha, Matricula, ctps_serie,Cbo,Pis,CargaHo,IdPessoa,IdInsp,IdCargo, IdSetor Setor, convert (varchar(10),DtNasc,103) DtNasc, convert (varchar(10),DtAdm,103) DtAdm, Email,Nome, CPF, Fone, Ativo,Assinatura from Funcionario f inner join Pessoa p on p.Id = f.IdPessoa where login = '{0}'", login);
                var retornoDataReader = contexto.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjeto(retornoDataReader).FirstOrDefault();
            }
        }

        public Funcionario ListarPorLoginSITAC(string cpf)
        {
            using (contextoPostgres = new ContextoPostgres())
            {
                var strQuery = String.Format(" SELECT usuario, nome,cpf,email,telefone FROM public.tb_usuarios where cpf = '{0}'", cpf);
                var retornoDataReader = contextoPostgres.ExecutaComandoComRetorno(strQuery);
                return TransformaReaderEmListaDeObjetoPostgres(retornoDataReader).FirstOrDefault();
            }
        }

        private List<Funcionario> TransformaReaderEmListaDeObjeto(SqlDataReader reader)
        {            
            var func = new List<Funcionario>();
            
            while (reader.Read())
            {
                CREAPA.Dominio.Pessoa pessoa = new CREAPA.Dominio.Pessoa();
                var TemObjeto = new Funcionario()
                {
                    Id = int.Parse(reader["Id"].ToString()),
                    Login = reader["Login"].ToString(),
                    Senha = reader["Senha"].ToString(),
                    Matricula = reader["Matricula"].ToString(),
                    Rg = reader["Rg"].ToString(),
                    ctps_serie = reader["ctps_serie"].ToString(),
                    Cbo = reader["Cbo"].ToString(),
                    Pis = reader["Pis"].ToString(),
                    CargaHo = reader["CargaHo"].ToString(),
                    IdPessoa = reader["IdPessoa"].ToString(),
                    IdInsp = reader["IdInsp"].ToString(),
                    IdCargo = reader["IdCargo"].ToString(),
                    DtNasc = reader["DtNasc"].ToString(),
                    DtAdm = reader["DtAdm"].ToString(),
                    Setor = reader["Setor"].ToString(),
                    Assinatura = GetBytes(reader["Assinatura"].ToString())
                };
                
                TemObjeto.Pessoa = pessoa;
                var TemObjetoPessoa = new Pessoa()
                {
                    Nome = reader["Nome"].ToString(),
                    CPF = reader["CPF"].ToString(),
                    Email = reader["Email"].ToString(),
                    Fone = reader["Fone"].ToString(),
                    Ativo = bool.Parse(reader["Ativo"].ToString())
                };
                TemObjeto.Pessoa.Nome = TemObjetoPessoa.Nome;
                TemObjeto.Pessoa.CPF = TemObjetoPessoa.CPF;
                TemObjeto.Pessoa.Email = TemObjetoPessoa.Email;
                TemObjeto.Pessoa.Fone = TemObjetoPessoa.Fone;
                TemObjeto.Pessoa.Ativo = TemObjetoPessoa.Ativo;

                func.Add(TemObjeto);
            }
            reader.Close();
            return func;
        }

        private static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        private List<Funcionario> TransformaReaderEmListaDeObjetoPostgres(NpgsqlDataReader reader)
        {
            var func = new List<Funcionario>();

            while (reader.Read())
            {
                CREAPA.Dominio.Pessoa pessoa = new CREAPA.Dominio.Pessoa();
                var TemObjeto = new Funcionario()
                {
                    Login = reader["usuario"].ToString()                    
                };

                TemObjeto.Pessoa = pessoa;
                var TemObjetoPessoa = new Pessoa()
                {
                    Nome = reader["nome"].ToString(),
                    CPF = reader["cpf"].ToString(),
                    Email = reader["email"].ToString(),
                    Fone = reader["telefone"].ToString()
                };
                TemObjeto.Pessoa.Nome = TemObjetoPessoa.Nome;
                TemObjeto.Pessoa.CPF = TemObjetoPessoa.CPF;
                TemObjeto.Pessoa.Email = TemObjetoPessoa.Email;
                TemObjeto.Pessoa.Fone = TemObjetoPessoa.Fone;                

                func.Add(TemObjeto);
            }
            reader.Close();
            return func;
        }
    }
}
